package com.flexrrb.managers
{
	import com.flexrrb.events.RightClickEvent;
	import com.flexrrb.utils.RightClickListener;
	
	import flash.display.DisplayObject;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import flash.external.ExternalInterface;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import mx.collections.ArrayCollection;
	import mx.controls.Menu;
	import mx.core.Application;
	import mx.events.InterManagerRequest;
	import mx.events.MenuEvent;
	import mx.managers.ISystemManager;

	[Event(name="rightClickShow", type="com.barcap.events.RightClickEvent")]
	[Event(name="rightClickHide", type="com.barcap.events.RightClickEvent")]
	[Event(name="rightClick", type="com.barcap.events.RightClickEvent")]

	public class RightClickManager extends EventDispatcher
	{
		public function RightClickManager(target:IEventDispatcher=null)
		{
			super(target);
		}
		private static var actualMenu:Menu;
		private static var listeners:ArrayCollection=new ArrayCollection();
		private static var currentListener:RightClickListener;

		public static function register(listenerObject:Object, comp:Object, menuXML:XMLList=null, receiverFunction:Function=null):void
		{
			initialize();
			var listener:RightClickListener=new RightClickListener();
			listener.listenerObject=listenerObject;
			listener.receiverFunction=receiverFunction;
			listener.component=comp;
			listener.menuXML=menuXML;
			if (!listeners.contains(listener))
			{
				listeners.addItem(listener);
			}
		}

		public static function initialize():void
		{
			ExternalInterface.addCallback("rightClick", handleRightClick);
		}

		private static function handleRightClick():void
		{
			if (actualMenu)
			{
				actualMenu.hide();
			}
			try
			{
				var pt:Point=new Point(Application.application.mouseX, Application.application.mouseY);
				pt=Application.application.localToGlobal(pt);
				var objects:Array=Application.application.systemManager.getObjectsUnderPoint(pt);
				if (objects.length > 0)
				{
					var object:Object;
					for (var i:Number=objects.length - 1; i >= 0; i--)
					{
						object=objects[i];
						var listener:RightClickListener=isExists(object.parent);
						if (listener)
						{
							currentListener=listener;
							actualMenu=Menu.createMenu(null, listener.menuXML, false);
							actualMenu.labelField="@label";
							actualMenu.addEventListener(MenuEvent.ITEM_CLICK, onMenuItemClick, false, 0, true);
							listener.component.dispatchEvent(new RightClickEvent(RightClickEvent.RIGHTCLICK_SHOW, listener.component, actualMenu));
							actualMenu.show(pt.x, pt.y);
							
							var sm:ISystemManager=Application.application.systemManager.topLevelSystemManager;
							var sbRoot:DisplayObject=sm.getSandboxRoot();
							var screen:Rectangle;
							if (sm != sbRoot)
							{
								var request:InterManagerRequest=new InterManagerRequest(InterManagerRequest.SYSTEM_MANAGER_REQUEST, false, false, "getVisibleApplicationRect");
								sbRoot.dispatchEvent(request);
								screen=Rectangle(request.value);
							}
							else
								screen=sm.getVisibleApplicationRect();

							if (pt.y + actualMenu.height > screen.bottom && pt.y > screen.top + actualMenu.height)
							{
								pt.y-=actualMenu.height;
							}
							if (pt.x + actualMenu.width > screen.right)
							{
								pt.x-=actualMenu.width;
							}
							actualMenu.move(pt.x, pt.y);
							return;
						}
					}
				}
			}
			catch (e:*)
			{
			}
		}

		private static function onMenuItemClick(event:MenuEvent):void
		{
			currentListener.component.dispatchEvent(new RightClickEvent(RightClickEvent.RIGHTCLICK_CLICK, currentListener.component, actualMenu, event.label));
			//currentListener.receiverFunction(event.label);
		}

		private static function isExists(obj:Object):RightClickListener
		{
			for each (var listener:RightClickListener in listeners)
			{
				if (obj == listener.component)
				{
					return listener;
				}
			}
			return null;
		}
	}
}
